/**********************************************************************
 *** *                                                            * ***
 *** *  Copyright (c) 2011 Harmonia Holdings Group LLC            * ***
 *** *                                                            * ***
 *** * Permission is hereby granted to use, modify, copy, and     * ***
 *** * distribute this software and its documentation for any     * ***
 *** * purpose only without profit, provided that the above       * ***
 *** * Copyright Notice appears in all copies and that both the   * ***
 *** * Copyright Notice and this Permission Notice appears in     * ***
 *** * every copy of supporting documentation.  No title to nor   * ***
 *** * ownership of the software is transferred hereby.  The name * ***
 *** * of Harmonia Holdings Group LLC shall not be used in        * ***
 *** * advertising or publicity related to the distribution of    * ***
 *** * the software without specific, written, prior permission.  * ***
 *** * This software is provided as-delivered without expressed   * ***
 *** * or implied warranty.  Harmonia Holdings Group LLC          * ***
 *** * makes no representation about the suitability of this      * ***
 *** * software for any purpose and accepts no responsibility for * ***
 *** * its use.                                                   * ***
 *** *                                                            * ***
 *** ************************************************************** ***
 *** *                                                            * ***
 *** * This program is free software; you can redistribute it     * ***
 *** * and/or modify it under the terms of the GNU General Public * ***
 *** * License as published by the Free Software Foundation;      * ***
 *** * either version 2 of the License, or (at your option) any   * ***
 *** * later version.                                             * ***
 *** *                                                            * ***
 *** * This program is distributed in the hope that it will be    * ***
 *** * useful, but WITHOUT ANY WARRANTY; without even the implied * ***
 *** * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR    * ***
 *** * PURPOSE.  See the GNU General Public License for more      * ***
 *** * details.                                                   * ***
 *** *                                                            * ***
 *** * You should have received a copy of the GNU General Public  * ***
 *** * License along with this program; if not, write to the Free * ***
 *** * Software Foundation, Inc., 51 Franklin Street, Fifth       * ***
 *** * Floor, Boston, MA 02110-1301, USA.                         * ***
 *** *                                                            * ***
 *** * For more information: http://www.gnu.org/licenses/gpl.html * ***
 *** *                                                            * ***
 **********************************************************************/
package org.etexascode.transceiver;

import com.sun.jersey.spi.container.servlet.ServletContainer;
import java.io.File;
import java.io.FileInputStream;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;


public class ServerAPI {

    
    final public static String TRANSCEIVER_PORT_PROP = "transceiver.port";
    
    private static String configFilePath;
    
    private static Server server;

    
    public static void main(String[] args) throws Exception {

        
        configFilePath = System.getProperty("config");
        if (configFilePath == null || configFilePath.isEmpty()) {
            configFilePath = "j2735-transceiver.properties";
        }

        
        loadProperties(configFilePath);

        
        String missingConfiguration = getMissingConfigurationProps();
        if (missingConfiguration.isEmpty()) {
            startServer();
        } else {
            Logger.getLogger(ServerAPI.class.getName()).log(Level.WARNING, "The following properties need to be configured: {0}", missingConfiguration);
            startServer();
        }

        
        server.join();
    }

    
    private static String getMissingConfigurationProps() {
        StringBuilder sb = new StringBuilder();

        String port = System.getProperty(TRANSCEIVER_PORT_PROP);
        if (port == null || port.isEmpty()) {
            sb.append(TRANSCEIVER_PORT_PROP);
        }

        return sb.toString();
    }

    
    private static void loadProperties(String configPath) throws Exception {
        File configFile = new File(configPath);
        if (configFile.isFile()) {

            Properties properties = new Properties();
            properties.load(new FileInputStream(configFile));

            for (Entry<Object, Object> entry : properties.entrySet()) {
                String key = (String) entry.getKey();
                String value = (String) entry.getValue();
                Logger.getLogger(ServerAPI.class.getName()).log(Level.CONFIG, "{0} = {1}", new String[]{key, value});

                
                
                if (System.getProperty(key) == null) {
                    System.setProperty(key, value);
                }
            }
        } else {
            Logger.getLogger(ServerAPI.class.getName()).log(Level.INFO, "No config file found at: {0}", configPath);
        }
    }

    
    public static void startServer() {
        
        String port = System.getProperty(TRANSCEIVER_PORT_PROP);
        if (port == null || port.isEmpty()) {
            port = "8888";
        }
        int portNum = Integer.parseInt(port);

        
        server = new Server(portNum);
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        ServletHolder servletHolder = new ServletHolder(new ServletContainer());
        servletHolder.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
        servletHolder.setInitParameter("com.sun.jersey.config.property.packages", "org.etexascode.transceiver.rest");
        context.addServlet(servletHolder, "/*");

        try {
            // Start the Jetty server
            server.start();
        } catch (Exception ex) {
            Logger.getLogger(ServerAPI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public static void joinServer() {
        try {
            if (server != null) {
                server.join();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(ServerAPI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    
    public static void stopServer() {
        try {
            if (server != null) {
                server.stop();
            }
        } catch (Exception ex) {
            Logger.getLogger(ServerAPI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
